﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace CoreCms.Net.Utility.Helper
{
    public class SignHelper
    {
        public string GetSign(Dictionary<string, string> paramsMap, string secret)
        {
            if (paramsMap == null || string.IsNullOrEmpty(secret))
            {
                return null;
            }

            // 提取 key 并排序
            var keyList = paramsMap.Keys.ToList();
            keyList.Sort();

            // 构造排序后的 key=value 字符串
            var sortedParams = new List<string>();
            foreach (var key in keyList)
            {
                if (!paramsMap.ContainsKey(key))
                {
                    return null;
                }

                try
                {
                    var value = HttpUtility.UrlEncode(paramsMap[key].Trim());
                    value = value.Replace("*", "%2A").Replace("+", "%20").Replace("%7E", "~");
                    sortedParams.Add($"{key}={value}");
                }
                catch (Exception)
                {
                    return null;
                }
            }

            try
            {
                // 拼接成字符串
                var sortString = string.Join("&", sortedParams);
                return GetSignature(sortString, secret).ToUpper();
            }
            catch (Exception)
            {
                return null;
            }
        }

        private string GetSignature(string data, string secret)
        {
            using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
            {
                byte[] hashBytes = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(data));
                return ByteArrayToHexString(hashBytes);
            }
        }

        private string ByteArrayToHexString(byte[] bytes)
        {
            var stringBuilder = new StringBuilder();
            foreach (var b in bytes)
            {
                stringBuilder.Append(b.ToString("x2"));
            }
            return stringBuilder.ToString();
        }

        /**
         * 消息验签
         * @param content 推送的 body 体内容
         * @param secret 商家密钥
         * @return
         */
        public bool VerifyMessageSign(string content, string secret)
        {
            try
            {
                if (string.IsNullOrEmpty(content) || string.IsNullOrEmpty(secret))
                {
                    throw new ArgumentNullException(nameof(content));
                }

                const string signKey = "sign";
                const string paramKey = "param";

                if (!content.Contains(signKey) || !content.Contains(paramKey))
                {
                    throw new Exception("Message error");
                }

                // 获取签名和参数
                string signPart = content.Substring(0, content.IndexOf("&param"));
                string sign = signPart.Replace($"{signKey}=", "");
                string paramsPart = content.Substring(content.IndexOf("&param=") + 7);

                // 验证签名
                return GetSignature(paramsPart, secret).ToUpper() == sign;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
